package com.umeox.watch.moto.alarm;


import static com.umeox.watch.moto.alarm.base.Constants.ALARM_EVERYDAY_REPEAT_EXP;

import android.app.Service;
import android.content.ContentValues;
import android.content.Context;
import android.media.AudioManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;

import com.umeox.moto.common.log.Logger;
import com.umeox.moto.common.utils.DateUtils;
import com.umeox.watch.moto.alarm.base.Constants;
import com.umeox.watch.moto.dataservice.DataProvider;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Utils {
    /**
     * 判断服务器闹钟时间格式是否正确 HH:mm
     */
    public static boolean is24HourFormatTime(String alarmTimeStr) {
        if (TextUtils.isEmpty(alarmTimeStr)) {
            return false;
        }
        String rexp = "^(([0-1][0-9])|2[0-3]):[0-5][0-9]$";
        Pattern pat = Pattern.compile(rexp);
        Matcher mat = pat.matcher(alarmTimeStr);
        return mat.matches();
    }

    /**
     * 判断时间段，重复周期格式是否正确
     * 正确格式：1100011  7个字节长度，只允许0或者1
     */
    public static boolean isInvalidRepeatExpression(String repeatExpression) {
        String rexp = "[0-1]{7}";
        return Pattern.compile(rexp).matcher(repeatExpression).matches();
    }

    /**
     * 根据重复周期解析成对应的字符串,例1100011，表示每周按星期天，星期一，星期五，星期六计算
     * 如果是1111111，返回每天
     * 如果是0000000，返回从不
     * exp长度与week数据长度必须一致
     *
     * @param exp               重复周期表达式
     * @param week              对应一周的一个描述数组
     * @param regularExpression 返回的字符串是用字符分割
     */
    public static String getRepeatDay(Context context, String exp, CharSequence[] week, char regularExpression) {
        if (TextUtils.isEmpty(exp)) {
            return "";
        }
        if (ALARM_EVERYDAY_REPEAT_EXP.equals(exp)) {
            return context.getResources().getString(R.string.every_day);
        } else if (Constants.ALARM_NOREPEAT_EXP.equals(exp)) {
            return context.getString(R.string.never);
        }
        if (week == null) {
            week = context.getResources().getStringArray(R.array.week_days_short);
        }
        int length = exp.length();

        if (length != week.length) {
            return "";
        }

        for (int i = 0; i < length; i++) {
            int expChar = Integer.parseInt(String.valueOf(exp.charAt(i)));
            if (expChar == 0) {
                week[i] = "";
            }
        }
        return combineStrings(week, regularExpression);
    }


    //重复周期只有星期天
    private static final String ONE_SUNDAY_EXP = "1000000";

    /***
     * 重新排序,周一>>>>周日
     * @param exp
     * @param repeatDay
     * @return 返回结果以周一为第一天, 周日最后一天
     */
    public static String monTOSunOrder(String exp, String repeatDay) {

        if (ONE_SUNDAY_EXP.equals(exp) || exp.equals(ALARM_EVERYDAY_REPEAT_EXP) || exp.indexOf("1") != 0) {
            return repeatDay;
        }
        String[] strings = repeatDay.split(" ");
        String string = strings[0];
        return repeatDay.substring(string.length() + 1) + " " + string;
    }

    /**
     * Combine a list of strings in an <code>Object[]</code> into a single
     * string.
     *
     * @param list non-null; the strings to combine
     * @return non-null; the combined form
     */
    public static String combineStrings(CharSequence[] list, char separator) {
        int listLength = list.length;

        if (listLength == 0) {
            return "";
        } else if (listLength == 1) {
            return (String) list[0];
        }

        int strLength = 0;

        for (Object o : list) {
            strLength += ((String) o).length();
        }

        StringBuilder sb = new StringBuilder(strLength);
        for (Object temp : list) {
            if (temp == null || TextUtils.isEmpty(temp.toString())) {
                continue;
            }
            sb.append(temp).append(separator);
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    public static List<AlarmDetail> getAlarmList() {
        return getAlarmList(true);
    }

    public static List<AlarmDetail> getAlarmList(boolean withoutLater) {
        ArrayList<AlarmDetail> list = new ArrayList<>();
        List<ContentValues> alarms = DataProvider.getAlarms();
        if (alarms != null && !alarms.isEmpty()) {
            for (ContentValues temp : alarms) {
                AlarmDetail alarm = AlarmDetail.convertFromValues(temp);
                if (alarm != null) {
                    if (withoutLater && alarm.getAlarmId() == Integer.MAX_VALUE) {
                        continue;
                    }
                    long tempTime = getNextAlarmTimeMillis(alarm);
                    if (tempTime > 0) {
                        alarm.setAlarmTimeInMillis(tempTime);
                    }
                    list.add(alarm);
                }
            }
        }
        Logger.i("获取闹钟：" + list);
        return list;
    }

    /**
     * 获取下次闹钟响铃的时间
     *
     * @param alarmList 闹钟列表
     */
    public static AlarmDetail getNextAlarmDetail(List<AlarmDetail> alarmList) {
        if (alarmList == null || alarmList.isEmpty()) {
            Logger.w("闹钟列表为空");
            return null;
        }
        List<AlarmDetail> temp = new ArrayList<>();
        for (AlarmDetail detail : alarmList) {
            if (!detail.isValid()) {
                continue;
            }

            if (detail.getAlarmTimeInMillis() > System.currentTimeMillis()) {
                temp.add(detail);
            }
        }

        AlarmDetail nextAlarm = null;
        for (AlarmDetail detail : temp) {
            Logger.i("每个闹钟，重复周期中距离现在最近的时间：" + DateUtils.formatDateTime(detail.getAlarmTimeInMillis()));
            if (nextAlarm == null
                    || nextAlarm.getAlarmTimeInMillis() > detail.getAlarmTimeInMillis()) {
                nextAlarm = detail;
            }
        }
        return nextAlarm;
    }

    /**
     * 获取闹钟具体的响铃时间
     *
     * @param detail 闹钟对象
     */
    public static long getNextAlarmTimeMillis(AlarmDetail detail) {
        final String repeatExpression = detail.getRepeatExpression();

        if (!isInvalidRepeatExpression(repeatExpression)) {
            return -1;
        }
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, detail.getHour());
        cal.set(Calendar.MINUTE, detail.getMinute());
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);

        final long timeInMillis = cal.getTimeInMillis();
        int currentDayOfWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;

        if (detail.isRepeat()) {
            final char[] weeks = repeatExpression.toCharArray();
            if (weeks[currentDayOfWeek] == '1'
                    && timeInMillis > System.currentTimeMillis()) {
                return timeInMillis;
            }

            if (repeatExpression.equals(ALARM_EVERYDAY_REPEAT_EXP)) {
                cal.add(Calendar.DAY_OF_MONTH, 1);
                return cal.getTimeInMillis();
            }

            int temp = 7;
            for (int i = 0; i < weeks.length; i++) {
                if (weeks[i] == '1') {
                    int j = i - currentDayOfWeek;
                    if (j <= 0) {
                        j = j + 7;
                    }
                    if (temp > j) {
                        temp = j;
                    }
                }
            }
            cal.add(Calendar.DAY_OF_MONTH, temp);
            return cal.getTimeInMillis();
        } else {
            if (detail.getAlarmId() > 0) {
                return timeInMillis;
            } else {
                //手表设置的闹钟，响铃时间小于当前时间，延后一天响铃
                if (timeInMillis <= System.currentTimeMillis()) {
                    cal.add(Calendar.DAY_OF_YEAR, 1);
                }
                return timeInMillis;
            }
        }
    }

    /**
     * 判断是否震动模式
     */
    public static boolean isMute(Context context) {
        AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        return audio.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE;
    }

    public static boolean phoneIsInUse(Context context) {
        /**
         * 返回电话状态
         *
         * CALL_STATE_IDLE 无任何状态时
         * CALL_STATE_OFFHOOK 接起电话时
         * CALL_STATE_RINGING 电话进来时
         */
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
        tm.getCallState();
        if (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE) {
            Logger.i("call state idle...");
            return false;
        } else if (tm.getCallState() == TelephonyManager.CALL_STATE_OFFHOOK) {
            Logger.i("call state offhook...");
            return true;
        } else if (tm.getCallState() == TelephonyManager.CALL_STATE_RINGING) {
            Logger.i("call state ringing...");
            return true;
        }
        return false;
    }

    /**
     * 获取12小时制格式
     *
     * @param time   10:00、23:22格式
     * @param locale
     * @return 返回 10:00 AM、11:22 PM格式
     */
    public static String to12HourFormat_AM_PM(String time, Locale locale) {
        try {
            SimpleDateFormat hourFormat = new SimpleDateFormat("hh:mm", locale);
            return DateFormat
                    .getTimeInstance(DateFormat.SHORT, locale)
                    .format(hourFormat.parse(time));
        } catch (ParseException e) {
            Log.e("DATEUTILS", "to12HourFormat_AM_PM", e);
        }
        return time;
    }

    /**
     * 获取12小时制格式
     *
     * @param time   10:00、23:22格式
     * @param locale
     * @return 返回 10:00、11:22格式
     */
    public static String to12HourFormat(String time, Locale locale) {
        try {
            SimpleDateFormat hourFormat = new SimpleDateFormat("hh:mm", locale);
            return hourFormat.format(hourFormat.parse(time));
        } catch (ParseException e) {
            Log.e("DATEUTILS", "to12HourFormat: ", e);
        }
        return time;
    }

    /**
     * 获取24小时制格式
     *
     * @param time   10:00、23:22格式
     * @param locale
     * @return 返回 10:00、11:22格式
     */
    public static String to24HourFormat(String time, Locale locale) {
        try {
            SimpleDateFormat hourFormat = new SimpleDateFormat("HH:mm", locale);
            return hourFormat.format(hourFormat.parse(time));
        } catch (ParseException e) {
            Log.e("DATEUTILS", "to24HourFormat: ", e);
        }
        return time;
    }
}
